package com.parenting.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.parenting.entities.SystemResourcesDO;
import com.parenting.enums.ResultEnum;
import com.parenting.exception.BaseException;
import com.parenting.mapper.SystemResourcesMapper;
import com.parenting.request.ResourcesTreeRequest;
import com.parenting.response.MenuTreeListResponse;
import com.parenting.service.SystemResourcesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.parenting.util.base.Result;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 资源表 服务实现类
 * </p>
 *
 * @author 烟台业达-王世玺
 * @since 2021-08-19
 */
@Service
public class SystemResourcesServiceImpl extends ServiceImpl<SystemResourcesMapper, SystemResourcesDO> implements SystemResourcesService {
    /***
     * 根据登录用户ID 获得 用户 菜单信息
     * @param userId
     * @return
     */
    @Override
    public MenuTreeListResponse findMenuListByUserId(String userId) {
        List<SystemResourcesDO> menuListByUserId = baseMapper.findMenuListByUserId(userId);
        // 当userId不存在用户信息, menuList 空的, 如果存在用户但没有分配权限就会有一条空记录
        if(CollectionUtils.isEmpty(menuListByUserId)
                || menuListByUserId.get(0) == null
        ) {
            throw  new BaseException(ResultEnum.ACCOUNT_UNREGISTER);
        }
        // 2. 获取集合中的目录和菜单放到一个集合中,按钮放到一个集合中
        // 存放目录和菜单集合的
        List<SystemResourcesDO> dirMenuList = new ArrayList<>();
        // 存放按钮集合的,只要权限标识code值
        List<String> buttonList = new ArrayList<>();
        for(SystemResourcesDO menu: menuListByUserId) {
            if(menu.getType()==3) {
                buttonList.add(menu.getCode()); // 按钮
            }else {
                dirMenuList.add(menu); // 目录和菜单
            }
        }
        // 3. 封装树状菜单
        List<SystemResourcesDO> menuTreeList = this.buildTree(dirMenuList);
        // 4. 响应数据
        MenuTreeListResponse menu=new MenuTreeListResponse();
        menu.setMenuTreeList(menuTreeList);
        menu.setButtonList(buttonList);
        return menu;
    }

    @Override
    public List<SystemResourcesDO> findByUserId(String userId) {
        List<SystemResourcesDO> menuListByUserId = baseMapper.findMenuListByUserId(userId);
        List<SystemResourcesDO> systemResourcesDOS = buildTree(menuListByUserId);
        if( CollectionUtils.isEmpty(menuListByUserId)
                || menuListByUserId.get(0) == null ) {
            return null;
        }
        return systemResourcesDOS;
    }

    @Override
    public Result<List<SystemResourcesDO>> queryTreeResources(ResourcesTreeRequest type) {
        QueryWrapper<SystemResourcesDO> sort = new QueryWrapper<SystemResourcesDO>();
        sort.orderByDesc("sort");
        sort.eq("terminal",1);
        boolean flag=true;
        if (type!=null&&null!=type.getType()){
            if (type.getType()!=3){
                sort.ne("type",3);
            }
            if (type.getType()==3){
                flag=false;
                sort.eq("type",3);
            }
        }
        List<SystemResourcesDO> resources=baseMapper.selectList(sort);
        return Result.ok(flag?buildTree(resources):resources);
    }

    @Override
    public List<String> findRoleResources(String roleId) {


        return  baseMapper.findRoleResources(roleId);
    }

    @Override
    public List<String> findRoleUser(String userId) {

        return baseMapper.findRoleUser(userId);

    }



    @Override
    public List<String> findCodeByUserId(String userId) {

        return baseMapper.findCodeByUserId(userId);
    }

    /**
     *  将菜单封装为树状结构
     * @param menuList 所有的菜单（目录、菜单、按钮）
     * @return 返回已经构建好树菜单集合
     */
    private List<SystemResourcesDO> buildTree(List<SystemResourcesDO> menuList) {
        // 1. 获取根菜单
        List<SystemResourcesDO> rootMenuList = new ArrayList<>();
        for(SystemResourcesDO menu: menuList) {
            // parentId=0为根菜单
            if(menu.getParentId().equals("0")) {
                rootMenuList.add(menu);
            }
        }
        // 2. 根菜单下的子菜单
        for(SystemResourcesDO menu: rootMenuList) {
            // 获取一个个根菜单，获取后再去获取对应的子菜单
            childrenMenu(menuList, menu);
        }
        // 所有根菜单对象中都将子菜单收集在了对应的children对象中
        return rootMenuList;
    }

    /**
     * 判断父菜单id是否等于所有菜单中的某一个菜单的parentId，如果等于，则这个菜单 就是子菜单
     * @param menuList 所有菜单（目录、菜单、按钮）
     * @param menu 父菜单对象
     * @return
     */
    private SystemResourcesDO childrenMenu(List<SystemResourcesDO> menuList, SystemResourcesDO menu) {
        // 存放menu菜单对象的所有子菜单
        List<SystemResourcesDO> children = new ArrayList<>();
        // 循环所有菜单，判断是否为 menu 的子菜单
        for(SystemResourcesDO m: menuList) {
            // 判断每个菜单的parentId是否等于menu对象中的id
            if(m.getParentId().equals( menu.getId() )) {
                children.add( childrenMenu(menuList, m) );
            }
        }
        menu.setChildren(children);
        return menu;
    }
}
